package com.fingard.dsp.bank.directbank.pab01;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.util.DateHelper;
import com.fingard.util.HttpClientUtil;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class PAB01SinglePay extends PAB01Base implements ISinglePay {
	public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);
		RetAtsSglDetail tmpRetDetail = null;
		if ("190802A".equals(p_req1908.reqHeader.commandCode)) {
			tmpRetDetail = d_190802A_KHKF03(p_req1908);
		} else if ("190803".equals(p_req1908.reqHeader.commandCode)) {
			tmpRetDetail = d_190803(p_req1908);
		} else {
			tmpRetDetail = d_190802(p_req1908);
		}
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/** 跨行快付 */
	private RetAtsSglDetail d_190802A_KHKF03(ReqSingle p_req1908) throws Exception {
		RetAtsSglDetail retDetail = new RetAtsSglDetail();
		retDetail.reqSeqID = p_req1908.singleDetail.askNumber;
		try {
			PAB01Header bankHeader = new PAB01Header();
			bankHeader.trncode = "KHKF03";
			bankHeader.fourZero = "0000";
			bankHeader.reqSeqNo = p_req1908.reqHeader.transSeqID;

			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.autoFormat = false;
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");
			XElement tmpXElement = new XElement("Result", "");

			tmpXElement.addChild(new XElement("OrderNumber", p_req1908.singleDetail.askNumber));
			tmpXElement.addChild(new XElement("AcctNo", p_req1908.singleDetail.payAct));
			String tmpBusiType = this.getBankConfig().getMapValueBySrcXE("BusiType_190802A_KHKF03", "srcCode", "desCode", p_req1908.singleDetail.srcXElement, "00000");
			tmpXElement.addChild(new XElement("BusiType", tmpBusiType));// 费项代码
			String tmpCorpId = this.getBankConfig().getSetValue("CorpId", "", new String[] { "KHKF03_" + this.bankFront.code, "KHKF03" });
			tmpXElement.addChild(new XElement("CorpId", tmpCorpId));
			tmpXElement.addChild(new XElement("CcyCode", convertCurToBank(p_req1908.singleDetail.payCur)));
			tmpXElement.addChild(new XElement("TranAmount", p_req1908.singleDetail.payAmount));
			tmpXElement.addChild(new XElement("InAcctNo", p_req1908.singleDetail.recAct));
			tmpXElement.addChild(new XElement("InAcctName", p_req1908.singleDetail.recName));
			if (StringHelper.hasAnyChar(p_req1908.singleDetail.recBankName)) {
				tmpXElement.addChild(new XElement("InAcctBankName", p_req1908.singleDetail.recBankName));
			} else {
				tmpXElement.addChild(new XElement("InAcctBankName", p_req1908.singleDetail.recBankLocation));
			}
			if (!"999999999999".equals(p_req1908.singleDetail.cnapsCode)) {
				tmpXElement.addChild(new XElement("InAcctBankNode", p_req1908.singleDetail.cnapsCode));
			} else {
				tmpXElement.addChild(new XElement("InAcctBankNode", ""));
			}
			tmpXElement.addChild(new XElement("Mobile", p_req1908.singleDetail.cellPhone));
			tmpXElement.addChild(new XElement("Remark", p_req1908.singleDetail.purpose));

			String[] provCity = p_req1908.singleDetail.getOppProvinceAndCity();
			tmpXElement.addChild(new XElement("InAcctProvinceName", provCity[0]));
			tmpXElement.addChild(new XElement("InAcctCityName", provCity[1]));

			nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());
			xmlWriter.writeXElement(tmpXElement);
			xmlWriter.writeEndDocument();

			String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

			if (tmpStrRet[0].length() == 0) {
				byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
				String tmpRetCode = new String(retBytes, 87, 6, getCharset());
				String tmpRetMsg = new String(retBytes, 93, 100, getCharset()).trim();
				tmpRetMsg = StringHelper.trimStart(tmpRetMsg, ":");
				if ("000000".equals(tmpRetCode)) {
					tmpStrRet[1] = tmpStrRet[1].substring(tmpStrRet[1].indexOf("<"));
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
					if (tmpBkReader != null) {
						retDetail.respCode = "0";
						retDetail.respInfo = tmpRetMsg.substring(1);
						if (tmpBkReader.read("/Result")) {
							retDetail.reqSeqID = tmpBkReader.readedXElement.getSingleTextNotNull("OrderNumber");
							retDetail.outTransID = tmpBkReader.readedXElement.getSingleTextNotNull("BussFlowNo");
						}
						retDetail.transState = "KHKF+" + tmpRetCode;
						retDetail.payInfoCode = tmpRetCode;
					} else {
						retDetail.respCode = "-1";
						retDetail.respInfo = tmpSbMsg.toString();
					}
				} else {
					retDetail.respCode = "0";
					retDetail.respInfo = tmpRetMsg;
					retDetail.transState = "KHKF+" + tmpRetCode + "+" + tmpRetMsg.trim();
					retDetail.payInfoCode = tmpRetCode;
					return retDetail;
				}
			} else if (tmpStrRet[0].equals(ConnState.FAIL)) {
				retDetail.respCode = "0";
				retDetail.respInfo = tmpStrRet[1];
				retDetail.transState = PaymentState.FAIL_Payment;
				retDetail.payInfoCode = tmpStrRet[0];
			} else {
				retDetail.respCode = "-1";
				retDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception ex) {
			FGBiz.limitMsg.exception(reqHeader.bankCode, ex);
			retDetail.respCode = "-1";
			retDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		return retDetail;
	}

	/** 跨行快付状态查询，KHKF03提交，通过KHKF04查询 */
	private RetAtsSingle d_1944_KHKF04(ReqQrySingle p_req1944) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
		RetAtsSglDetail tmpRetAtsDetail = new RetAtsSglDetail();

		try {

			if (StringHelper.isNullOrEmpty(p_req1944.payAct)) {
				throw new Exception("请求报文缺失PayAct");
			}

			PAB01Header bankHeader = new PAB01Header();
			bankHeader.trncode = "KHKF04";
			bankHeader.fourZero = "0000";
			bankHeader.reqSeqNo = p_req1944.reqHeader.transSeqID;

			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.autoFormat = false;
			xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding=\"" + getCharset() + "\"?>");

			xmlWriter.writeStartElement("Result");
			xmlWriter.writeElementString("AcctNo", p_req1944.payAct);
			xmlWriter.writeElementString("OrderNumber", p_req1944.askNumber);
			xmlWriter.writeElementClosed("BussFlowNo");
			xmlWriter.writeEndDocument();

			String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

			if (tmpStrRet[0].length() == 0) {

				byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
				String tmpRetCode = new String(retBytes, 87, 6, getCharset());
				String tmpRetMsg = new String(retBytes, 93, 100, getCharset()).trim();
				tmpRetMsg = StringHelper.trimStart(tmpRetMsg, ":");

				if ("000000".equals(tmpRetCode)) {
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1].substring(tmpStrRet[1].indexOf("<")), tmpSbMsg);
					if (tmpBkReader != null) {
						if (tmpBkReader.read("/Result")) {

							tmpRetAtsDetail.respCode = "0";
							tmpRetAtsDetail.respInfo = tmpBkReader.readedXElement.getSingleTextNotNull("RetMsg");
							tmpRetAtsDetail.reqSeqID = tmpBkReader.readedXElement.getSingleTextNotNull("OrderNumber");
							tmpRetAtsDetail.transAmt = tmpBkReader.readedXElement.getSingleText("TranAmount");
							tmpRetAtsDetail.transState = "KHKF+" + tmpBkReader.readedXElement.getSingleText("Status");// 20成功，30失败，其余处理中。
							String payInfoCode = tmpRetAtsDetail.respInfo;
							// 提取<RetMsg>，如果有“:”并且“:”之后有字符，则提取“:”之后的字符，否则提取整个<RetMsg>字符，
							if (payInfoCode.indexOf(':') > -1 && payInfoCode.length() - (payInfoCode.indexOf(':') + 1) > 0) {
								payInfoCode = payInfoCode.substring(payInfoCode.indexOf(':') + 1);
							}
							tmpRetAtsDetail.payInfoCode = payInfoCode;
							tmpRetAtsDetail.outTransID = tmpBkReader.readedXElement.getSingleTextNotNull("BussFlowNo");
						}
					} else {
						tmpRetAtsDetail.respCode = "-1";
						tmpRetAtsDetail.respInfo = tmpSbMsg.toString();
					}
				} else {
					tmpRetAtsDetail.respCode = "-1";
					tmpRetAtsDetail.respInfo = tmpRetMsg;
					if (tmpRetMsg.contains("没有满足条件的记录") || tmpRetMsg.contains("没有满足条件纪录")) {
						if (canBeNotExist(p_req1944, tmpRetAtsDetail, 30)) {
							tmpRetAtsDetail.respCode = "0";
							tmpRetAtsDetail.reqSeqID = p_req1944.askNumber;
							tmpRetAtsDetail.payInfoCode = tmpRetCode;
							tmpRetAtsDetail.transState = "KHKF+" + tmpRetCode;
						}
					}
				}
			} else {
				tmpRetAtsDetail.respCode = "-1";
				tmpRetAtsDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception ex) {
			FGBiz.limitMsg.exception(reqHeader.bankCode, ex);
			tmpRetAtsDetail.respCode = "-1";
			tmpRetAtsDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetAtsDetail);
		return retAts;
	}

	/**
	 *	平安付商户充值接口
	 *  参考文档：平安付商户充值接口：http://test-open.stg.yqb.com/moap/business/api_shcz_cz?type=api_shcz&ele=api_shcz_cz
	 *
	 *  @author fanh
	 *
	 */
	private RetAtsSglDetail d_190803(ReqSingle p_req1908) throws Exception {
		RetAtsSglDetail retAts = new RetAtsSglDetail(p_req1908);
        retAts.reqSeqID = p_req1908.singleDetail.askNumber;

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.recAct, "");
			if (actItem != null) {
				// content组装
				JSONObject content = new JSONObject();
				Map contents = new LinkedHashMap();

				content.put("version", "1.0.0");
				contents.put("version", "1.0.0");
				content.put("merchantNo", actItem.merchantId);
				contents.put("merchantNo", actItem.merchantId);
				// clientSeqNo客户端交易流水号
				content.put("clientSeqNo", p_req1908.reqHeader.reqSeqID);
				contents.put("clientSeqNo", p_req1908.reqHeader.reqSeqID);
				// clientTxTime 商户发起交易的时间，时间格式yyyyMMddHHmmss
				content.put("clientTxTime", Format.DateTime14Format.format(DateHelper.convertToDateExtra(p_req1908.reqHeader.transTime)));
				contents.put("clientTxTime", Format.DateTime14Format.format(DateHelper.convertToDateExtra(p_req1908.reqHeader.transTime)));
				// accountType 05：商户现金户 07：商户付款专户
				String accountType = getBankConfig().getValueAsString("accountType");
				if (StringHelper.hasAnyChar(accountType)) {
					content.put("accountType", accountType);
					contents.put("accountType", accountType);
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "请求报文中accountType节点为空，请检查PAB01/config.xml中'accountType'节点配置";
					return retAts;
				}
				// bankCardIndex 标识银行卡，平安付CCDC卡索引，线下提供给商户
                String bankCardIndex = getBankConfig().getValueAsString("bankCardIndex");
                if (StringHelper.hasAnyChar(bankCardIndex)) {
                    content.put("bankCardIndex", bankCardIndex);
                    contents.put("bankCardIndex", bankCardIndex);
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = "请求报文中bankCardIndex节点为空，请检查PAB01/config.xml中'bankCardIndex'节点配置";
                    return retAts;
                }
				// amount 充值金额，1000000表示1元
				content.put("amount", amountMultiply1000000(p_req1908.singleDetail.payAmount));
				contents.put("amount", amountMultiply1000000(p_req1908.singleDetail.payAmount));

				content.put("signMethod", "RSA");
                WriteBankLogLn("待签名数据:" + convertMapToStr(contents));
				String privateKey = getBankConfig().getValueAsString("privateKey");
				if (StringHelper.hasAnyChar(privateKey)) {
					String signature = sign(convertMapToStr(contents), privateKey);
					content.put("signature", signature);
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "请求报文中privateKey节点为空，请检查PAB01/config.xml中'privateKey'节点配置";
					return retAts;
				}
				// content明文
				String content1 = content.toJSONString();
				WriteBankLogLn("content明文:" + content1);
				// content密文
				String contentS = "";
				String aesKey = getBankConfig().getValueAsString("aesKey");
				if (StringHelper.hasAnyChar(aesKey)) {
					contentS = encrypt4Aes(content1, aesKey, "UTF-8");
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "请求报文中aesKey节点为空，请检查PAB01/config.xml中'aesKey'节点配置";
					return retAts;
				}
				WriteBankLogLn("content密文:" + contentS);

				// 组装报文
				Map<String, Object> inputS = new HashMap<String, Object>();
				inputS.put("content", contentS);
				inputS.put("hashFunc", "SHA-1");
				String systemId = getBankConfig().getValueAsString("systemId");
				if (StringHelper.hasAnyChar(systemId)) {
					inputS.put("systemId", systemId);
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "请求报文中systemId节点为空，请检查PAB01/config.xml中'systemId'节点配置";
					return retAts;
				}
				inputS.put("serviceCode", "R0376");
				String hashFuncKey = getBankConfig().getValueAsString("hashFuncKey");
				if (StringHelper.hasAnyChar(hashFuncKey)) {
					inputS.put("token", encryptPwd(content1 + hashFuncKey, "SHA-1", "UTF-8"));
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "请求报文中hashFuncKey节点为空，请检查PAB01/config.xml中'hashFuncKey'节点配置";
					return retAts;
				}

				String inputString = JSON.toJSONString(inputS);
				WriteBankLogStep2(inputString);

				String tmpStrRet = HttpClientUtil.executeJsonPost(bankFront.serverURL, inputString);

				WriteBankLogStep3(tmpStrRet);
				if (!"".equals(tmpStrRet) && tmpStrRet != null) {
					JSONObject respBizContent = JSON.parseObject(tmpStrRet);
					String respCode = respBizContent.getString("code");
					String tmpRespInfo = respBizContent.getString("memo");
					if (respCode != null && "000000".equals(respCode)) {
						String contentStr = respBizContent.getString("content");
						String contentJson = decrypt4Aes2Str(contentStr, aesKey, "UTF-8");
						JSONObject respContent = JSONObject.parseObject(contentJson);
						WriteBankLogLn("银行返回的content内容为："+ respContent.toJSONString());
                        String tmpRespCode = respContent.getString("respCode");
						if (tmpRespCode != null && "000000".equals(tmpRespCode)) {
                            retAts.respCode = "0";
                            retAts.respInfo = respContent.getString("memo");
                            String status = respContent.getString("status");
                            if (StringHelper.hasAnyChar(status)) {
                                retAts.transState = tmpRespCode + "+" + status;
                                retAts.payInfoCode = tmpRespCode + "+" + status;
                            } else {
                                retAts.transState = tmpRespCode + "+" + status;
                                retAts.payInfoCode = status;
                            }
                        } else {
						    retAts.respCode = "0";
						    retAts.respInfo = respContent.getString("memo");
                        }
					} else {
                        retAts.respCode = "0";
                        retAts.respInfo = tmpRespInfo;
					}
				} else {
					retAts.respCode = "-1";
					retAts.respInfo = "银行响应内容为空,请联系银行咨询!";
					retAts.transState = PaymentState.FAIL;
					retAts.payInfoCode = FailCode.E9981;
				}
			} else {
				retAts.respCode = "0";
				retAts.respInfo = "未找到账号:[" + p_req1908.singleDetail.payAct	+ "]商户配置信息,请检查config.xml中'actSet'节点相关配置信息!";
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = FailCode.E9981;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.respCode = "-1";
			retAts.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		return retAts;
	}

	private RetAtsSglDetail d_190802(ReqSingle p_req1908) throws Exception {
		RetAtsSglDetail retDetail = new RetAtsSglDetail();
		try {
			PAB01Header bankHeader = new PAB01Header();
			bankHeader.trncode = "4004";
			bankHeader.fourZero = "0000";
			bankHeader.reqSeqNo = p_req1908.reqHeader.transSeqID;

			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.autoFormat = false;
			writeCommonHeader(xmlWriter);

			XElement tmpXElement = new XElement("Result", "");
			// ThirdVoucher -- 转账凭证号
			tmpXElement.addChild(new XElement("ThirdVoucher", p_req1908.singleDetail.askNumber));
			tmpXElement.addChild(new XElement("CcyCode", convertCurToBank(p_req1908.singleDetail.payCur)));

			// 付方
			tmpXElement.addChild(new XElement("OutAcctNo", p_req1908.singleDetail.payAct));
			tmpXElement.addChild(new XElement("OutAcctName", p_req1908.singleDetail.payName));
			tmpXElement.addChild(new XElement("OutAcctAddr", p_req1908.singleDetail.payBankLocation));
			// 收方
			tmpXElement.addChild(new XElement("InAcctBankNode", p_req1908.singleDetail.cnapsCode));
			tmpXElement.addChild(new XElement("InAcctRecCode", p_req1908.singleDetail.cnapsCode));
			tmpXElement.addChild(new XElement("InAcctNo", p_req1908.singleDetail.recAct));
			tmpXElement.addChild(new XElement("InAcctName", p_req1908.singleDetail.recName));
			tmpXElement.addChild(new XElement("InAcctBankName", p_req1908.singleDetail.recBankLocation));

			tmpXElement.addChild(new XElement("TranAmount", p_req1908.singleDetail.payAmount));
			// UseEx -- 资金用途
			tmpXElement.addChild(new XElement("UseEx", p_req1908.singleDetail.purpose));
			// UnionFlag -- 行内跨行标志 1.行内转账 0.跨行转账
			tmpXElement.addChild(new XElement("UnionFlag", ("1".equals(p_req1908.singleDetail.sameBnk) ? ("1") : ("0"))));
			// SysFlag -- 转账加急标志
			tmpXElement.addChild(new XElement("SysFlag", "1".equals(p_req1908.singleDetail.paySpd) ? "Y" : "N"));
			// AddrFlag -- 同城/异地标志
			tmpXElement.addChild(new XElement("AddrFlag", ("1".equals(p_req1908.singleDetail.sameCity) ? ("1") : ("2"))));

			nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, getCharset());

			xmlWriter.writeXElement(tmpXElement);
			xmlWriter.writeEndDocument();

			String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

			if (tmpStrRet[0].length() == 0) {
				byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
				String tmpRetCode = new String(retBytes, 87, 6, getCharset());
				String tmpRetMsg = new String(retBytes, 93, 100, getCharset()).trim();
				if ("000000".equals(tmpRetCode)) {
					tmpStrRet[1] = tmpStrRet[1].substring(tmpStrRet[1].indexOf("<"));
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
					if (tmpBkReader != null) {
						retDetail.respCode = "0";
						retDetail.respInfo = tmpRetMsg.substring(1);
						if (tmpBkReader.read("/Result")) {
							retDetail.reqSeqID = tmpBkReader.readedXElement.getSingleTextNotNull("ThirdVoucher");
							retDetail.outTransID = tmpBkReader.readedXElement.getSingleTextNotNull("FrontLogNo");
						}
						retDetail.transState = tmpRetCode;
						retDetail.payInfoCode = tmpRetCode;
					} else {
						retDetail.respCode = "-1";
						retDetail.respInfo = tmpSbMsg.toString();
					}
				} else {
					retDetail.respCode = "0";
					retDetail.respInfo = tmpRetMsg;
					retDetail.transState = tmpRetCode;
					retDetail.payInfoCode = tmpRetCode;
					return retDetail;
				}
			} else if (tmpStrRet[0].equals(ConnState.FAIL)) {
				retDetail.respCode = "0";
				retDetail.respInfo = tmpStrRet[1];
				retDetail.transState = PaymentState.FAIL_Payment;
				retDetail.payInfoCode = tmpStrRet[0];
			} else {
				retDetail.respCode = "-1";
				retDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception ex) {
			FGBiz.limitMsg.exception(reqHeader.bankCode, ex);
			retDetail.respCode = "-1";
			retDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		return retDetail;
	}

	/** 接口入口 */
	public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
		if ("190802A".equals(p_req1944.reqHeader.commandCode)) {
			return d_1944_KHKF04(p_req1944);// 跨行快付状态查询
		} else if ("190803".equals(p_req1944.reqHeader.commandCode)) {
			return d_1944_190803(p_req1944);
		} else {
			return d_1944_190802(p_req1944);
		}
	}

	/** 单笔支付状态查询 */
	private RetAtsSingle d_1944_190802(ReqQrySingle p_req1944) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1944);

		try {
			PAB01Header bankHeader = new PAB01Header();
			bankHeader.trncode = "4005";
			bankHeader.fourZero = "0000";
			bankHeader.reqSeqNo = p_req1944.reqHeader.transSeqID;

			XmlTextWriter xmlWriter = new XmlTextWriter();
			xmlWriter.autoFormat = false;
			writeCommonHeader(xmlWriter);

			xmlWriter.writeStartElement("Result");
			xmlWriter.writeElementString("OrigThirdVoucher", p_req1944.askNumber);
			xmlWriter.writeEndDocument();

			String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), bankHeader);

			if (tmpStrRet[0].length() == 0) {
				byte[] retBytes = tmpStrRet[1].getBytes(getCharset());
				String tmpRetCode = new String(retBytes, 87, 6, getCharset());
				String tmpRetMsg = StringHelper.trimStart(new String(retBytes, 93, 100, getCharset()).trim(), ":");

				if ("000000".equals(tmpRetCode)) {
					tmpStrRet[1] = tmpStrRet[1].substring(tmpStrRet[1].indexOf("<"));
					StringBuilder tmpSbMsg = new StringBuilder();
					XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
					if (tmpBkReader != null) {
						if (tmpBkReader.read("/Result")) {
							String respCodeAndInfo = tmpBkReader.readedXElement.getSingleTextNotNull("Yhcljg");
							String[] strCodeAndInfo = respCodeAndInfo.split(":");
							String strCode = strCodeAndInfo[0];
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = tmpBkReader.readedXElement.getSingleTextNotNull("Yhcljg");

							String stt = tmpBkReader.readedXElement.getSingleText("Stt");
							if (!"20".equals(stt) && !"30".equals(stt)) {
								tmpRetDetail.transState = "000000+99";
							} else {
								tmpRetDetail.transState = strCode + "+" + stt;
							}
							tmpRetDetail.payInfoCode = strCode;
							tmpRetDetail.transAmt = tmpBkReader.readedXElement.getSingleText("TranAmount");
							tmpRetDetail.outTransID = tmpBkReader.readedXElement.getSingleText("OrigFrontLogNo");
						}
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpSbMsg.toString();
					}
				} else {
					if ("YQ9996".equals(tmpRetCode) || tmpRetMsg.contains("没有满足条件纪录")) {
						if (!canBeNotExist(p_req1944, tmpRetDetail, 30)) {
							retAts.writeRetDetail(tmpRetDetail);
							return retAts;
						}
						tmpRetDetail.respCode = "0";
						tmpRetDetail.respInfo = tmpRetMsg;
						tmpRetDetail.transState = tmpRetCode;
						tmpRetDetail.payInfoCode = tmpRetCode;
						tmpRetDetail.reqSeqID = p_req1944.askNumber;
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpRetMsg;
					}
				}
			} else {
				tmpRetDetail.respCode = "-1";
				tmpRetDetail.respInfo = tmpStrRet[1];
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}

		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	/**
	 *	平安付商户充值接口
	 *  参考文档：平安付商户充值接口：http://test-open.stg.yqb.com/moap/business/api_shcz_cz?type=api_shcz&ele=api_shcz_cz
	 *
	 *  @author fanh
	 *
	 */
	private RetAtsSingle d_1944_190803(ReqQrySingle p_req1944) throws Exception {
		RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
		RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1944);

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.recAct, "");
			if (actItem != null) {
				// content组装
				JSONObject content = new JSONObject();
				Map contents = new LinkedHashMap();

				// version 接口版本号
				content.put("version", "1.0.0");
				contents.put("version", "1.0.0");
				// merchantNo 商户号
				content.put("merchantNo", actItem.merchantId);
				contents.put("merchantNo", actItem.merchantId);
				// clientSeqNo 客户端交易流水号
				content.put("clientSeqNo", p_req1944.askNumber);
				contents.put("clientSeqNo", p_req1944.askNumber);
				// signMethod 签名方法
				content.put("signMethod", "RSA");
				WriteBankLogLn("待签名数据:" + convertMapToStr(contents));
				String privateKey = getBankConfig().getValueAsString("privateKey");
				if (StringHelper.hasAnyChar(privateKey)) {
					String signature = sign(convertMapToStr(contents), privateKey);
					content.put("signature", signature);
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "请求报文中privateKey节点为空，请检查PAB01/config.xml中'privateKey'节点配置";
					retAts.writeRetDetail(tmpRetDetail);
					return retAts;
				}
				// content明文
				String content1 = content.toJSONString();
				WriteBankLogLn("content明文:" + content1);
				// content密文
				String contentS = "";
				String aesKey = getBankConfig().getValueAsString("aesKey");
				if (StringHelper.hasAnyChar(aesKey)) {
					contentS = encrypt4Aes(content1, aesKey, "UTF-8");
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "请求报文中aesKey节点为空，请检查PAB01/config.xml中'aesKey'节点配置";
					retAts.writeRetDetail(tmpRetDetail);
					return retAts;
				}
				WriteBankLogLn("content密文:" + contentS);

				// 组装报文
				Map<String, Object> inputS = new HashMap<String, Object>();
				inputS.put("content", contentS);
				inputS.put("hashFunc", "SHA-1");
				String systemId = getBankConfig().getValueAsString("systemId");
				if (StringHelper.hasAnyChar(systemId)) {
					inputS.put("systemId", systemId);
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "请求报文中systemId节点为空，请检查PAB01/config.xml中'systemId'节点配置";
					retAts.writeRetDetail(tmpRetDetail);
					return retAts;
				}
				inputS.put("serviceCode", "R0378");
				String hashFuncKey = getBankConfig().getValueAsString("hashFuncKey");
				if (StringHelper.hasAnyChar(hashFuncKey)) {
					inputS.put("token", encryptPwd(content1 + hashFuncKey, "SHA-1", "UTF-8"));
				} else {
					tmpRetDetail.respCode = "-1";
					tmpRetDetail.respInfo = "请求报文中hashFuncKey节点为空，请检查PAB01/config.xml中'hashFuncKey'节点配置";
					retAts.writeRetDetail(tmpRetDetail);
					return retAts;
				}
				String inputString = JSON.toJSONString(inputS);
				WriteBankLogStep2(inputString);
				String tmpStrRet = HttpClientUtil.executeJsonPost(bankFront.serverURL, inputString);
				WriteBankLogStep3(tmpStrRet);
				if (!"".equals(tmpStrRet) && tmpStrRet != null) {
					JSONObject respBizContent = JSON.parseObject(tmpStrRet);
					String contentStr = respBizContent.getString("content");
					String contentJson = decrypt4Aes2Str(contentStr, aesKey, "UTF-8");
					JSONObject respContent = JSONObject.parseObject(contentJson);
					String respCode = respBizContent.getString("code");
					String tmpRespInfo = respBizContent.getString("memo");
					if (respCode != null && "000000".equals(respCode)) {
						String tmpRespCode = respContent.getString("respCode");
						if (tmpRespCode != null && "000000".equals(tmpRespCode)) {
							tmpRetDetail.respCode = "0";
							tmpRetDetail.respInfo = respContent.getString("memo");
							String status = respContent.getString("status");
							if (StringHelper.hasAnyChar(status)) {
								tmpRetDetail.transState = tmpRespCode + "+" + status;
								tmpRetDetail.payInfoCode = tmpRespCode + "+" + status;
							} else {
								tmpRetDetail.transState = tmpRespCode + "+" + status;
								tmpRetDetail.payInfoCode = status;
							}
						} else {
							tmpRetDetail.respCode = "-1";
							tmpRetDetail.respInfo = respContent.getString("memo");
						}
					} else {
						tmpRetDetail.respCode = "-1";
						tmpRetDetail.respInfo = tmpRespInfo;
					}
				} else {
					tmpRetDetail.respInfo = "银行响应内容为空,请联系银行咨询!";
					tmpRetDetail.transState = PaymentState.FAIL;
					tmpRetDetail.payInfoCode = FailCode.E9981;
				}
			} else {
				tmpRetDetail.respCode = "0";
				tmpRetDetail.respInfo = "未找到账号:[" + p_req1944.payAct	+ "]商户配置信息,请检查config.xml中'actSet'节点相关配置信息!";
				tmpRetDetail.transState = PaymentState.FAIL_Batch;
				tmpRetDetail.payInfoCode = FailCode.E9981;
			}
		} catch (Exception ex) {
			ex.printStackTrace();
			tmpRetDetail.respCode = "-1";
			tmpRetDetail.respInfo = ex.getMessage();
			WriteBankLogLn(ex);
		}
		retAts.writeRetDetail(tmpRetDetail);
		return retAts;
	}

	@Override
	public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
		return null;
	}

	@Override
	public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
		return null;
	}
}
